package cloud.xuxiaowei.gateway.handler;

import cloud.xuxiaowei.utils.Response;
import cloud.xuxiaowei.utils.ResponseUtils;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 网关异常 处理程序
 *
 * @author xuxiaowei
 * @since 0.0.1
 */
@Setter
@Slf4j
@Component
public class GatewayErrorWebExceptionHandler implements ErrorWebExceptionHandler, Ordered {

	public static final int ORDERED = Ordered.HIGHEST_PRECEDENCE + 10000;

	private int order = ORDERED;

	@Override
	public int getOrder() {
		return this.order;
	}

	@NonNull
	@Override
	public Mono<Void> handle(@NonNull ServerWebExchange exchange, @NonNull Throwable ex) {

		ServerHttpResponse response = exchange.getResponse();

		log.error("网关异常处理器：", ex);

		Response<?> error;

		if (ex instanceof ResponseStatusException) {
			ResponseStatusException responseStatusException = (ResponseStatusException) ex;

			HttpStatus status = responseStatusException.getStatus();

			if (status == HttpStatus.NOT_FOUND) {
				// 404 Not Found
				error = Response.error(HttpStatus.NOT_FOUND.value(), "访问地址不存在");
			}
			else if (status == HttpStatus.SERVICE_UNAVAILABLE) {
				// 503 Service Unavailable
				error = Response.error(HttpStatus.SERVICE_UNAVAILABLE.value(), "服务不可用，请稍后再试或联系管理员");
			}
			else {
				error = Response.error(String.format("未处理异常状态：%s，请联系管理员", status.value()));
			}
		}
		else {
			error = Response.error("未判断异常类型，请联系管理员");
		}

		return ResponseUtils.writeWith(response, error);
	}

}
